package com.sxkawzp.area.dao;

import com.sxkawzp.area.domain.AdministrativeDivision;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;

/**
 * @author suxingkang
 * @version 1.0
 * @since 2025/1/21 9:05
 */
@Repository
public class AreaDao {

    private final JdbcTemplate jdbcTemplate;

    private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    public AreaDao(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
    }

    public AdministrativeDivision selectByAreaCode(String areaCode) {
        if (!StringUtils.hasText(areaCode)) {
            return null;
        }
        List<AdministrativeDivision> query = jdbcTemplate.query("select * from administrative_division where area_code = ?", BeanPropertyRowMapper.newInstance(AdministrativeDivision.class), areaCode);
        return getSingleResult(query);
    }

    public AdministrativeDivision selectById(Integer id) {
        if (Objects.isNull(id)) {
            return null;
        }
        List<AdministrativeDivision> query = jdbcTemplate.query("select * from administrative_division where id = ?", BeanPropertyRowMapper.newInstance(AdministrativeDivision.class), id);
        return getSingleResult(query);
    }


    public List<AdministrativeDivision> selectByAncestorAndLftAndRgt(Integer ancestor, Integer lft, Integer rgt) {
        String sql = "SELECT id,area_name, area_code, pid, lft, rgt, lev, ancestor, sort, area_range from administrative_division where ancestor =? and lft <=? and rgt >=? ORDER BY lev";
        return jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(AdministrativeDivision.class), ancestor, lft, rgt);
    }

    public List<AdministrativeDivision> selectChildByAreaCode(Integer ancestor, int lft, int rgt) {
        return jdbcTemplate.query("select id,area_name, area_code, pid, lft, rgt, lev, ancestor, sort, area_range from administrative_division where ancestor = ? and lft >= ? and rgt <= ? "
                , BeanPropertyRowMapper.newInstance(AdministrativeDivision.class), ancestor, lft, rgt);
    }


    public int updateLft(Integer ancestor, Integer lft) {
        String sql = "update administrative_division set lft=lft+2 where ancestor = ? and lft > ?";
        return jdbcTemplate.update(sql, ancestor, lft);
    }


    public int updateRgt(Integer ancestor, Integer lft) {
        String sql = "update administrative_division set rgt=rgt+2 where ancestor = ? and rgt >= ?";
        return jdbcTemplate.update(sql, ancestor, lft);
    }


    public AdministrativeDivision insert(AdministrativeDivision administrativeDivision) {
        String sql = "insert into administrative_division(area_name, area_code, pid, lft, rgt, lev, ancestor, sort, area_range) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
        jdbcTemplate.update(sql,
                administrativeDivision.getAreaName(),
                administrativeDivision.getAreaCode(),
                administrativeDivision.getPid(),
                administrativeDivision.getLft(),
                administrativeDivision.getRgt(),
                administrativeDivision.getLev(),
                administrativeDivision.getAncestor(),
                administrativeDivision.getSort(),
                administrativeDivision.getAreaRange()
        );

        String lastIdSql = "select last_insert_id()";
        Integer id = jdbcTemplate.queryForObject(lastIdSql, Integer.class);
        administrativeDivision.setId(id);
        return administrativeDivision;
    }


    public int update(AdministrativeDivision administrativeDivision) {
        String sql = "update administrative_division " +
                "set area_name  = ?, " +
                "    area_code  = ?, " +
                "    area_range = ?, " +
                "    ancestor = ?, " +
                "    sort       = ? " +
                "where id = ? ";
        return jdbcTemplate.update(sql,
                administrativeDivision.getAreaName(),
                administrativeDivision.getAreaCode(),
                administrativeDivision.getSort(),
                administrativeDivision.getAreaRange(),
                administrativeDivision.getAncestor(),
                administrativeDivision.getId()
        );
    }


    private <T> T getSingleResult(List<T> results) {
        if (CollectionUtils.isEmpty(results)) {
            return null;
        }
        return results.get(0);
    }

}
